package com.gagakuai.scripting.defaults;

import com.gagakuai.executor.parameter.ParameterHandler;
import com.gagakuai.mapping.BoundSql;
import com.gagakuai.mapping.MappedStatement;
import com.gagakuai.mapping.ParameterMapping;
import com.gagakuai.mapping.ParameterMode;
import com.gagakuai.session.Configuration;
import com.gagakuai.type.JdbcType;
import com.gagakuai.type.TypeException;
import com.gagakuai.type.TypeHandler;
import org.springframework.util.CollectionUtils;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;

/*
 * @program: common-starters
 * @description: 默认的参数解析器
 * @author: houhong
 * @create: 2023-06-30 21:14
 */
public class DefaultParameterHandler implements ParameterHandler {

    /*
     * 对statement的处理
     */
    private final MappedStatement mappedStatement;
    /*
     * 参数对象
     */
    private final Object parameterObject;
    /*
     * 绑定的sql
     */
    private final BoundSql boundSql;
    /*
     * 配置
     */
    private final Configuration configuration;

    public DefaultParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql, Configuration configuration) {
        this.mappedStatement = mappedStatement;
        this.parameterObject = parameterObject;
        this.boundSql = boundSql;
        this.configuration = configuration;
    }

    @Override
    public Object getParameterObject() {
        return parameterObject;
    }


    /*
     * @param ps:预处理
     * @return
     * @Author houhong
     * @Description 设置参数
     * @Date 9:31 下午 2023/6/30
     */
    @Override
    public void setParameters(PreparedStatement ps) throws SQLException {

        // 参数对应的类型处理器
        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();

        if (CollectionUtils.isEmpty(parameterMappings)) {
            return;
        }
        int index = 1;
        for (ParameterMapping parameterMapping : parameterMappings) {
            if (parameterMapping.getMode() == ParameterMode.OUT) {
                continue;
            }

            Object value = null;
            //属性名
            String propertyName = parameterMapping.getProperty();
            //根据参数名获取值
            if (boundSql.hasAdditionalParameter(propertyName)) {
                value = boundSql.getAdditionalParameter(propertyName);
            } else if (parameterObject == null) {
                value = null;
            }// todo

            //类型处理器
            TypeHandler typeHandler = parameterMapping.getTypeHandler();
            //jdbc参数
            JdbcType jdbcType = parameterMapping.getJdbcType();
            if (value == null && jdbcType == null) {
                jdbcType = configuration.getJdbcTypeForNull();
            }

            try {
                /*
                 * 调用TypeHandler的setParameter方法，为Statement对象参数占位符设置值
                 */
                typeHandler.setParameter(ps, index, value, jdbcType);
            } catch (TypeException e) {
                throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e);
            } catch (SQLException e) {
                throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e);
            }
        }


    }
}